package com.cbw.server;

import com.cbw.bean.Express;
import com.cbw.dao.ExpressDao;
import com.cbw.dao.impI.ExpressDaoImpI;
import com.cbw.utils.MsgUtil;

import java.io.IOException;
import java.net.Socket;

/**
 * 服务器端线程任务，实现快递增删改查，实际上是调用Dao进行具体实现
 */
public class ExpressRunnable implements Runnable {
    private Socket socket; //声明
    private ExpressDao dao=new ExpressDaoImpI();

    /**
     * 构造器，在服务器端获取客户端连接socket，从而可获取客户端传递来的信息
     * @param accept
     */
    public ExpressRunnable(Socket accept) {
        this.socket = accept;
    }

    @Override
    public void run() {//线程任务
        while(true){
            try {
                //服务器接收客户端传递来的命令
                String cmd = MsgUtil.receiveCmd(socket);
                if (cmd==null) break;
                switch (cmd){
                    case MsgUtil.CMD_ADD: //添加命令
                        System.out.println("服务器端开始执行添加操作");
                        addExpress();
                        break;
                    case MsgUtil.CMD_CHECKE_FULL: //判满命令
                        checkFull();
                        break;
                    case MsgUtil.CMD_REMOVE://删除命令
                        System.out.println("服务器端开始执行删除命令");
                        removeExpress();
                        break;
                    case MsgUtil.CMD_FIND_BY_NUMBER:
                        System.out.println("服务器开始通过单号查找快递是否存在");
                        findNumber();
                        break;
                    case MsgUtil.CMD_MODIFY:
                        System.out.println("服务器开始修改快递信息");
                        modifyExpress();
                        break;
                    case MsgUtil.CMD_QUERY:
                        System.out.println("服务器开始查询所有快递信息");
                        findAll();
                        break;
                    case MsgUtil.CMD_PICK:
                        System.out.println("服务器开始取快递");
                        pickExpress();
                        break;
                    default:
                        System.out.println("无此指令");
                        break;
                }
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
                try{
                    socket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                break;
            }
        }
    }

    /**
     * 服务器取快递
     * 即通过取件码删除数据
     * 先接收客户端传递参数code
     * 然后调用dao去根据code删除
     * 然后响应客户端数据
     */
    private void pickExpress() throws IOException {
        int code = MsgUtil.receiveInt(socket);//接收取件码code
        Express express = dao.removeByCode(code);//取出快递
        MsgUtil.sendExpress(socket,express);//响应客户端，返回被删除数据
    }

    /**
     * 服务器调用Dao查询所有快递信息
     * 客户端ExpressClient中findAll方法中并没有向服务器传递数据，这里不需接收
     * 但客户端在等着接收服务器返回的查询结果，这里要向客户端发送查询结果
     */
    private void findAll() throws IOException {
        MsgUtil.sendList(socket,dao.getAll());
    }

    /**服务器调用dao修改快递信息
     * 客户端ExpressClient中modifyExpress方法向服务器发送修改命令，开始执行下面方法，
     * 并传递两个快递对象，在下面进行接收
     */
    private void modifyExpress() throws IOException, ClassNotFoundException {
        //接收客户端传递的两个快递对象
        Express oldExpress = MsgUtil.receiveExpress(socket);
        Express newExpress = MsgUtil.receiveExpress(socket);
        Express modify = dao.modify(oldExpress, newExpress);//调用dao去操作数据修改
        MsgUtil.sendExpress(socket,modify);//响应客户端，回写数据，将修改后的快递返回
    }

    /**
     * 服务器端调用DAO查询指定单号快递是否存在
     * ExpressClient客户端中findByNumber方法向服务器发送命令和参数，在这里接收参数
     */
    private void findNumber() throws IOException {
        String number = MsgUtil.receiveCmd(socket);
        int index = dao.findByNumber(number);
        MsgUtil.sendInt(socket,index);//服务器将查询数据发送到客户端，客户端一直等待接收
    }

    /**
     * 服务器调用DAO删除指定单号的数据
     */
    private void removeExpress() throws IOException {
        String number = MsgUtil.receiveCmd(socket);
        //客户端发送删除命令，在这里接收命令，并读取传递来的number单号
        boolean remove = dao.removeByNumber(number);//调用DAO删除指定数据，返回布尔
        MsgUtil.sendBoolean(socket,remove);//服务器将布尔结果回写，客户端还在等着接收

    }

    /**
     * 服务器端调用dao判断快递柜是否已满，将结果直接发送到客户端，客户端调用方法接收
     */
    private void checkFull() throws IOException {
        MsgUtil.sendBoolean(socket,dao.checkFull());
    }

    /**
     * 服务器添加数据，调用DAO进行快递添加操作
     */
    private void addExpress() throws IOException, ClassNotFoundException {
        Express express = MsgUtil.receiveExpress(socket);//服务器接收客户端传递的快递
        Express add= dao.add(express);  //调用dao添加数据
        MsgUtil.sendExpress(socket,add);//将添加结果发送给客户端
    }
}
